#include "TcpServer.h"

namespace mp_net
{
	void TcpServer::SetIoService(spIoService ioService)
	{
		while(!TryLock()){Pause(MPN_TCP_MTX_LOCK_DELAY);}
		TcpSession::SetIoService(ioService);
		UpdateAcceptor();
		Unlock();
	}

	TcpServer::~TcpServer()
	{
		StopThread();
		delete m_acceptor;
	}

	void TcpServer::UpdateAcceptor()
	{
		m_acceptor = new tcp::acceptor(
			*m_ioService, 
			tcp::endpoint(tcp::v4(), MPN_TCP_DEF_PORT));
	}

	//Threading -----------------------

	void TcpServer::ThreadInitialization()
	{
		TcpSession::ThreadInitialization();
	}

	void TcpServer::ThreadUpdate()
	{
		AsyncAccept(); //Sockets only accessed on worker thread
		TcpSession::ThreadUpdate();
	}

	void TcpServer::ThreadShutdown()
	{
		TcpSession::ThreadShutdown();
	}

	//Acceptor Threading -----------------------

	void TcpServer::AsyncAccept()
	{
		//If we are not already waiting for a connection
		if ( !m_accepting )
		{
			//State to the console that we are now looking for a client
			std::cout << "[TcpServer] Starting Async Accept\n";
			//Set the accepting flag to true
			m_accepting = true;
			//Setup new socket for looking
			m_socket[m_socketCount] = new tcp::socket(*m_ioService);
			//Start async accept  
			m_acceptor->async_accept(*m_socket[m_socketCount], 
				boost::bind(
					&TcpServer::AsyncAcceptProc,
					this,
					boost::asio::placeholders::error));
		}

	}

	void TcpServer::AsyncAcceptProc(
		const boost::system::error_code& error)
	{
		//Completion of async accept  
		if (error)
		{
			m_accepting = false;
			delete m_socket[m_socketCount];
			m_socket[m_socketCount] = NULL;
			std::cout << "[TcpServer] Error: "<< error.message() << "\n";
		}
		else
		{
			m_socketCount++;
			m_accepting = false;
			std::cout << "[TcpServer] Starting Async Completed\n";
		}
	}


}